package com.platform.core.web.controller;

import cn.hutool.core.map.MapUtil;
import com.google.common.base.Strings;
import com.google.common.collect.Maps;
import com.platform.aspect.WebLog;
import com.platform.comm.exceptions.RestApiException;
import com.platform.comm.jwt.JwtTokenUtil;
import com.platform.comm.jwt.TokenInfoUtil;
import com.platform.comm.validation.groups.Pwd;
import com.platform.comm.web.results.DataJsonResult;
import com.platform.comm.web.results.JsonResult;
import com.platform.core.security.auth.AuthenticationFacade;
import com.platform.core.service.NcloudSysNotifyBiz;
import com.platform.core.service.SysRoleFunctionService;
import com.platform.core.service.SysUserService;
import com.platform.dto.FunctionQo;
import com.platform.dto.NcloudSysNotifyDto;
import com.platform.dto.PwdQo;
import com.platform.dto.RoleQo;
import com.platform.dto.UserDetail;
import com.platform.enums.FunctionType;
import com.platform.enums.RoleEnum;
import com.platform.enums.SysNotifyUserType;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.PageRequest;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * Description: 个人信息
 *
 * @author libin Created on 2019/7/15
 **/
@Slf4j
@RestController
public class ProfileController extends BaseController {
    private final SysUserService sysUserService;
    private final SysRoleFunctionService sysRoleFunctionService;
    private final NcloudSysNotifyBiz ncloudSysNotifyBiz;
    private final TokenInfoUtil tokenInfoUtil;

    public ProfileController(SysUserService sysUserService, SysRoleFunctionService sysRoleFunctionService, NcloudSysNotifyBiz ncloudSysNotifyBiz, TokenInfoUtil tokenInfoUtil) {
        this.sysUserService = sysUserService;
        this.sysRoleFunctionService = sysRoleFunctionService;
        this.ncloudSysNotifyBiz = ncloudSysNotifyBiz;
        this.tokenInfoUtil = tokenInfoUtil;
    }

    @PostMapping("/user/info")
    @WebLog(theme = "用户登录", moduleName = "登录管理", type = WebLog.OpType.LOG_IN, root = Integer.class)
    public DataJsonResult<Map<String, Object>> info(HttpServletRequest request) {
        Map<String, Object> result = Maps.newHashMap();
        JwtTokenUtil.JwtUser jwtUser = tokenInfoUtil.getUser();
        if (jwtUser != null) {
            UserDetail userDetail = sysUserService.findByUsername(jwtUser.getUsername());
            if (Objects.nonNull(userDetail)) {
                result.put("id", userDetail.getId());
                result.put("userType", userDetail.getUserType());
                result.put("mobile", userDetail.getMobile());
                result.put("email", userDetail.getEmail());
                result.put("username", jwtUser.getUsername());
                result.put("realName", jwtUser.getRealName());
                // 获取部门
                result.put("departId", userDetail.getDepartId());
                result.put("departCode", userDetail.getDepartCode());
                result.put("departName", userDetail.getDepartName());
                result.put("departKind", userDetail.getDepartKind());
                result.put("avatarFileId", userDetail.getAvatarFileId());
                // 获取角色
                List<RoleQo> list = userDetail.getRoles();
                // 解决首页修改角色问题
                result.put("roles",list);
                result.put("roleCodes", list.parallelStream().map(RoleQo::getCode).collect(Collectors.joining(", ")));
                result.put("roleNames", list.parallelStream().map(RoleQo::getName).collect(Collectors.joining(", ")));
                // 查询菜单 权限
                queryFunctions(result, list);
                //未读信息
                List<NcloudSysNotifyDto> ncloudSysNotifyDtos = ncloudSysNotifyBiz.search(MapUtil.of("status", SysNotifyUserType.UNREAD.name()), PageRequest.of(0, 5)).getContent();
                result.put("hasUnReadNotify", ncloudSysNotifyDtos.stream().filter(ncloudSysNotifyDto -> "0".equals(ncloudSysNotifyDto.getStatus())).count() > 0);
                result.put("newNotifyData", ncloudSysNotifyDtos);
            }
        } else {
            throw new RestApiException("用户信息查询失败");
        }
        return DataJsonResult.succeed(result);
    }

    private void queryFunctions(Map<String, Object> map, List<RoleQo> list) {
        long count = list.parallelStream().map(RoleQo::getCode).filter(RoleEnum.ROLE_ADMIN.name()::equalsIgnoreCase).count();
        Set<FunctionQo> set = sysRoleFunctionService.findFunctionByAdmin();
//        if (count > 0) {
//            // ROLE_ADMIN
//            set = sysRoleFunctionService.findFunctionByAdmin();
//        } else {
//            set = sysRoleFunctionService.findFunctionByRole(list.parallelStream().map(RoleQo::getId).collect(Collectors.toList()));
//        }
        map.put("functions", set.parallelStream().filter(qo -> FunctionType.FUN.equals(qo.getType()))
                .map(FunctionQo::getPath)
                .filter(path -> !Strings.isNullOrEmpty(path)));
        Map<String, List<FunctionQo>> groupMap = set.parallelStream().filter(qo -> FunctionType.ACT.equals(qo.getType()))
                .collect(Collectors.groupingBy(FunctionQo::getParentId));
        Map<String, List<String>> acts = Maps.newHashMap();
        groupMap.forEach(
                (key, val) -> set.parallelStream().filter(qo -> FunctionType.FUN.equals(qo.getType()) && key.equals(qo.getId()))
                        .map(FunctionQo::getPath)
                        .findFirst()
                        .ifPresent(path -> acts.put(path, val.parallelStream().map(FunctionQo::getPath).collect(Collectors.toList()))));
        map.put("permissions", acts);
    }

    @PostMapping(name = "修改用户密码", path = "/user/modifyPwd")
    public JsonResult modifyPwd(@Validated(Pwd.class) @RequestBody PwdQo ccbRequestBody) {
        return modify(sysUserService::modifyPwd, AuthenticationFacade.getUserName(), ccbRequestBody);
    }

    @GetMapping(name = "获取许可状态", path = "/lic/check")
    public JsonResult lic() {
//        LicenseVerify licenseVerify = new LicenseVerify();
//        // 校验证书是否有效
//        boolean verifyResult = licenseVerify.verify();
//        if (verifyResult) {
//            return JsonResult.success();
//        } else {
//            return JsonResult.failed("您的证书无效，请核查服务器是否取得授权或重新申请证书");
//        }
        return null;
    }
}
